/********************************************************************
 * PROJECT: FOLIAGE PROJECT.
 * SUPPLIER: FOLIAGE TEAM.
 ********************************************************************
 * FILE: AbstractMutableTreeNode.java
 * (C) Copyright Foliage Team 2013, All Rights Reserved.
 ********************************************************************/
package org.foliage.common.structure.impl;

import java.util.Arrays;
import java.util.List;

import org.foliage.common.structure.MutableTreeNode;

/**
 * 易变的一般有序树结点数据结构对象抽象类。
 * 
 * @author deathknight0718@gmail.com
 * @version 1.0.0
 */
public abstract class AbstractMutableTreeNode extends AbstractTreeNode implements MutableTreeNode {

	// ----------------------------------------------- ATTRIBUTE

	/** 父结点实例。 */
	AbstractMutableTreeNode parent;
	/** 子结点实例数组。 */
	AbstractMutableTreeNode[] children;

	// ----------------------------------------------- CONSTRUCTOR

	public AbstractMutableTreeNode() {}

	// ----------------------------------------------- METHOD

	public boolean hasChild() {
		return children != null && children.length != 0;
	}

	public AbstractMutableTreeNode getChild(String key) {
		if (key != null && hasChild()) {
			for (AbstractMutableTreeNode child : getChildren()) {
				if (key.equals(child.getKey())) return child;
			}
		}
		return null;
	}

	public AbstractMutableTreeNode getChild(int index) {
		if (hasChild() && index < children.length) {
			return children[index];
		}
		return null;
	}

	public void add(AbstractMutableTreeNode treeNode) {
		if (treeNode != null && children == null) {
			children = new AbstractMutableTreeNode[1];
			children[0] = treeNode;
		} else if (treeNode != null) {
			List<AbstractMutableTreeNode> childList = Arrays.asList(children);
			childList.add(treeNode);
			treeNode.setParent(this);
			children = childList.toArray(new AbstractMutableTreeNode[0]);
		}
	}

	public void add(AbstractMutableTreeNode treeNode, int index) {
		if (treeNode != null && hasChild() && index < children.length) {
			List<AbstractMutableTreeNode> childList = Arrays.asList(children);
			childList.add(index, treeNode);
			// TODO(deathknight0718@gmail.com): 设置子结点的父子关联，下方类同。
			treeNode.setParent(this);
			children = childList.toArray(new AbstractMutableTreeNode[0]);
		}
	}

	public void remove(String key) {
		if (key != null && hasChild()) {
			List<AbstractMutableTreeNode> childList = Arrays.asList(children);
			for (AbstractMutableTreeNode child : childList) {
				if (key.equals(child.getKey())) {
					childList.remove(child);
				}
			}
			children = childList.toArray(new AbstractMutableTreeNode[0]);
		}
	}

	public void remove(int index) {
		if (hasChild() && index < children.length) {
			List<AbstractMutableTreeNode> childList = Arrays.asList(children);
			childList.remove(index);
			children = childList.toArray(new AbstractMutableTreeNode[0]);
		}
	}

	public void removeFormParent() {
		if (parent != null && parent.hasChild()) {
			List<AbstractMutableTreeNode> brotherList = Arrays.asList(parent.getChildren());
			for (AbstractMutableTreeNode brother : brotherList) {
				if (getKey().equals(brother.getKey())) brotherList.remove(brother);
			}
			parent.setChildren(brotherList.toArray(new AbstractMutableTreeNode[0]));
		}
	}

	// ----------------------------------------------- GETTER&&SETTER

	public AbstractMutableTreeNode getParent() {
		return parent;
	}

	public void setParent(AbstractMutableTreeNode parent) {
		// TODO(deathknight0718@gmail.com): 设置父结点的父子关联。
		if (parent != null) {
			parent.add(this);
		}
		this.parent = parent;
	}

	public AbstractMutableTreeNode[] getChildren() {
		return children;
	}

	public void setChildren(AbstractMutableTreeNode[] children) {
		// TODO(deathknight0718@gmail.com): 设置子结点数组的父子关联。
		if (children != null) {
			this.children = null;
			for (AbstractMutableTreeNode child : children) {
				child.setParent(this);
			}
		}
		this.children = children;
	}

}
